using System;
using System.IO;
using System.Diagnostics;
using Evaluant.Uss.Configuration;
using System.Configuration;

namespace Evaluant.Uss.Migrate
{
	class Program
	{
		[STAThread]
		static int Main(string[] args)
		{

			string config;
			string source;
			string target;
			bool init = false;
			bool bulk = false;

			#region Arguments

			ArgParser parser = new ArgParser(args);

			if (parser.Exists("?"))
			{
				Help();
				return 0;
			}

			//if (!parser.Exists("config"))
			//{
			//    Console.WriteLine("Incorrect parameters : no configuration file is defined");
			//    Help();
			//    return 1;
			//}

			config = parser["config"].Value;

			//if (!File.Exists(config))
			//{
			//    Console.WriteLine("The configuration file does not exist.");
			//    Help();
			//    return 2;
			//}

			if (!parser.Exists("source"))
			{
				Console.WriteLine("Incorrect parameters : no source repository defined");
				Help();
				return 3;
			}

			if (!parser.Exists("target"))
			{
				Console.WriteLine("Incorrect parameters : no target repository defined");
				Help();
				return 3;
			}

			if (!parser.Exists("silent"))
				System.Diagnostics.Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));

			source = parser["source"].Value;
			target = parser["target"].Value;

			IPersistenceProvider sourceProvider;
			IPersistenceProvider targetProvider;
			if (!string.IsNullOrEmpty(config))
			{
				try
				{
					sourceProvider = XmlConfigLoader.LoadXmlConfig(config, source);
					targetProvider = XmlConfigLoader.LoadXmlConfig(config, target);
				}
				catch (UniversalStorageException)
				{
					EussConfiguration eussConfig = (EussConfiguration)ConfigurationManager.OpenExeConfiguration(config).GetSection("evaluant.uss");
					sourceProvider = ConfigLoader.LoadConfig(eussConfig, source);
					targetProvider = ConfigLoader.LoadConfig(eussConfig, target);
				}
			}
			else
			{
				EussConfiguration eussConfig = (EussConfiguration)ConfigurationManager.GetSection("evaluant.uss");
				sourceProvider = ConfigLoader.LoadConfig(eussConfig, source);
				targetProvider = ConfigLoader.LoadConfig(eussConfig, target);
			}

			if (sourceProvider == null)
			{
				Console.WriteLine("Incorrect parameters : source section not found in configuration");
				return 4;
			}

			if (targetProvider == null)
			{
				Console.WriteLine("Incorrect parameters : source section not found in configuration");
				return 4;
			}

			init = parser.Exists("init");
			bulk = parser.Exists("bulk");

			#endregion

			try
			{
				IPersistenceEngine sourceEngine = sourceProvider.CreatePersistenceEngine();
				IPersistenceEngine targetEngine = targetProvider.CreatePersistenceEngine();

				if (init)
					targetEngine.InitializeRepository();

				XmlConfigLoader.ImportRepository(sourceEngine, targetEngine, bulk);

			}
			catch (Exception e)
			{
				Console.WriteLine("An error occured during the migration. Details:");
				Console.WriteLine(e.ToString());
				return 4;
			}

			return 0;
		}

		static public void Help()
		{
			Console.WriteLine(@"

Help for migrate.exe

Copies all the data from a repository to another one.

migrate.exe /config:config_filename /source:source_config_name /target:target_config_name [/init] [/bulk] [/silent]

	config_filename
		The Euss Configuration filename containing
        repositories information

	source_config_name
		The name of the configuration section to use as 
        the source repository

	target_config_name
		The name of the configuration section to use as 
        the target repository

	/init
		Whether the target repository should be initialized 
        before the migration

	/bulk
		Whether a single transaction should be used or not. This can improve the performances
        for some providers

	/silent
		Whether the trace should not be displayed

example:
migrate.exe /config:engines.config /source:""data (xml)"" /target:""data (sql)"" /init
");
		}
	}
}
